#include <limits>

#include <QString>
#include <QtTest>

#include <math/MSc_Angles3.h>

////////////////////////////////////////////////////////////////////////////////

class MSc_Angles3Test : public QObject
{
    Q_OBJECT

public:

    MSc_Angles3Test();

private Q_SLOTS:

    void testConstructor();

    void testIsValid();

    void testPhi();
    void testTht();
    void testPsi();

    void testSet();

    void testGetFrom();

    void testOperatorAssign();
    void testOperatorEqualTo();
    void testOperatorNotEqualTo();
};

////////////////////////////////////////////////////////////////////////////////

MSc_Angles3Test::MSc_Angles3Test() {}

////////////////////////////////////////////////////////////////////////////////

void MSc_Angles3Test::testConstructor()
{
    MSc_Angles3 angl_1;

    QVERIFY( angl_1.phi() == 0.0 );
    QVERIFY( angl_1.tht() == 0.0 );
    QVERIFY( angl_1.psi() == 0.0 );

    angl_1.phi() = 1.0;
    angl_1.tht() = 2.0;
    angl_1.psi() = 3.0;

    MSc_Angles3 angl_2( angl_1 );

    QVERIFY( angl_2.phi() == 1.0 );
    QVERIFY( angl_2.tht() == 2.0 );
    QVERIFY( angl_2.psi() == 3.0 );

    MSc_Angles3 angl_3( &angl_1 );

    QVERIFY( angl_3.phi() == 1.0 );
    QVERIFY( angl_3.tht() == 2.0 );
    QVERIFY( angl_3.psi() == 3.0 );
}

////////////////////////////////////////////////////////////////////////////////

void MSc_Angles3Test::testIsValid()
{
    MSc_Angles3 angl;

    angl.phi() = 1.0;
    angl.tht() = 2.0;
    angl.psi() = 3.0;

    QVERIFY( angl.isValid() );

    angl.phi() = std::numeric_limits< double >::quiet_NaN();
    angl.tht() = 2.0;
    angl.psi() = 3.0;

    QVERIFY( !angl.isValid() );

    angl.phi() = 1.0;
    angl.tht() = std::numeric_limits< double >::quiet_NaN();
    angl.psi() = 3.0;

    QVERIFY( !angl.isValid() );

    angl.phi() = 1.0;
    angl.tht() = 2.0;
    angl.psi() = std::numeric_limits< double >::quiet_NaN();

    QVERIFY( !angl.isValid() );

    angl.phi() = std::numeric_limits< double >::quiet_NaN();
    angl.tht() = std::numeric_limits< double >::quiet_NaN();
    angl.psi() = 3.0;

    QVERIFY( !angl.isValid() );

    angl.phi() = std::numeric_limits< double >::quiet_NaN();
    angl.tht() = 2.0;
    angl.psi() = std::numeric_limits< double >::quiet_NaN();

    QVERIFY( !angl.isValid() );

    angl.phi() = 1.0;
    angl.tht() = std::numeric_limits< double >::quiet_NaN();
    angl.psi() = std::numeric_limits< double >::quiet_NaN();

    QVERIFY( !angl.isValid() );

    angl.phi() = std::numeric_limits< double >::quiet_NaN();
    angl.tht() = std::numeric_limits< double >::quiet_NaN();
    angl.psi() = std::numeric_limits< double >::quiet_NaN();

    QVERIFY( !angl.isValid() );
}

////////////////////////////////////////////////////////////////////////////////

void MSc_Angles3Test::testPhi()
{
    MSc_Angles3 angl;

    angl.phi() = 1.0;

    QVERIFY( angl.phi() == 1.0 );
}

////////////////////////////////////////////////////////////////////////////////

void MSc_Angles3Test::testTht()
{
    MSc_Angles3 angl;

    angl.tht() = 1.0;

    QVERIFY( angl.tht() == 1.0 );
}

////////////////////////////////////////////////////////////////////////////////

void MSc_Angles3Test::testPsi()
{
    MSc_Angles3 angl;

    angl.psi() = 1.0;

    QVERIFY( angl.psi() == 1.0 );
}

////////////////////////////////////////////////////////////////////////////////

void MSc_Angles3Test::testSet()
{
    MSc_Angles3 angl;

    angl.set( 1.0, 2.0, 3.0 );

    QVERIFY( angl.phi() == 1.0 );
    QVERIFY( angl.tht() == 2.0 );
    QVERIFY( angl.psi() == 3.0 );
}

////////////////////////////////////////////////////////////////////////////////

void MSc_Angles3Test::testGetFrom()
{
    MSc_Angles3 angl = MSc_Angles3::getFrom( 1.0, 2.0, 3.0 );

    QVERIFY( angl.phi() == 1.0 && angl.tht() == 2.0 && angl.psi() == 3.0 );
}

////////////////////////////////////////////////////////////////////////////////

void MSc_Angles3Test::testOperatorAssign()
{
    MSc_Angles3 angl1;
    MSc_Angles3 angl2 = MSc_Angles3::getFrom( 1.0, 2.0, 3.0 );

    angl1 = angl2;

    QVERIFY( angl1.phi() == 1.0 && angl1.tht() == 2.0 && angl1.psi() == 3.0 );
}

////////////////////////////////////////////////////////////////////////////////

void MSc_Angles3Test::testOperatorEqualTo()
{
    MSc_Angles3 angl1 = MSc_Angles3::getFrom( 1.0, 2.0, 3.0 );
    MSc_Angles3 angl2 = MSc_Angles3::getFrom( 1.0, 2.0, 3.0 );

    QVERIFY( angl1 == angl2 );

    angl1.phi() = 0.0;

    QVERIFY( !( angl1 == angl2 ) );

    angl1.tht() = 0.0;

    QVERIFY( !( angl1 == angl2 ) );

    angl1.psi() = 0.0;

    QVERIFY( !( angl1 == angl2 ) );
}

////////////////////////////////////////////////////////////////////////////////

void MSc_Angles3Test::testOperatorNotEqualTo()
{
    MSc_Angles3 angl1 = MSc_Angles3::getFrom( 1.0, 2.0, 3.0 );
    MSc_Angles3 angl2 = MSc_Angles3::getFrom( 1.0, 2.0, 3.0 );

    QVERIFY( !( angl1 != angl2 ) );

    angl1.phi() = 0.0;

    QVERIFY( angl1 != angl2 );

    angl1.tht() = 0.0;

    QVERIFY( angl1 != angl2 );

    angl1.psi() = 0.0;

    QVERIFY( angl1 != angl2 );
}

////////////////////////////////////////////////////////////////////////////////

QTEST_APPLESS_MAIN(MSc_Angles3Test)

////////////////////////////////////////////////////////////////////////////////

#include "tst_msc_angles3test.moc"
